Skip to content

TypeORM 规则

实体目录

每一个实体目录对应数据库下的一张实体表

  1. 在实体目录下建立对应 实体类 .entity.ts 文件,定义表字段和表关联关系
  2. 在实体目录下建立对应 控制器 .controller.ts 文件,定义路由,基础增删改查路由和一多关联路由
  3. 在实体目录下建立对应 逻辑层 .service.ts 文件,定义与数据库交互逻辑,sql 操作在此
  4. 在实体目录下建立对应 模块层 .module.ts 文件,定义模块,汇集 entity、controller、service 三者,最终在 app.module.ts 中注册生效

实战总结

  1. 每个实体文件都有基础的增删改查方法,外加关联操作的增删改查方法
  2. 关联操作全部放在非用户实体目录下(放在哪一方都可以,推荐非用户方),防止用户目录逻辑复杂
  3. 关联操作要放在最上方,防止动态路由覆盖无效

注意事项

  1. 查询单条,必须用 param 动态路由参数,或者 param 与 query 参数组合因为 restful API 请求中查询的 path 是相同的,通过param 参数来区分查询单条还是多条
  2. 关联查询创建 POST 接口,在使用 APIpost 工具创建数据的时候无法插入 外键字段 ,解决方式:在实体中必须显式的定义外键字段
  3. 关联查询是双向的,即:关联查询接口定义的位置,既可以在 user的 service 中,也可以在自身的 service 中实现(建议在 自身 目录下实现)
  4. 关联操作,使用到用户id user_id 的参数的地方,现在是通过http参数,实际开发中要通过解析 token 获取 user_id
  5. 在 .service.ts 中进行多对多关联操作时,如果使用其他实体关系,要在 .module.ts 中注册其他实体的实体类
  6. 使用动态路由的时候注意:如果 path 相同,动态路由在上的时候会覆盖拦截下方的路由,因此 path 长的路由要放在最上面 /api/v1/roles/byUser 在上 /api/v1/roles/3 在下,否则 /api/v1/roles/byUser 会被覆盖无效
  7. 在 app.nodule.ts 中完成 mysql 数据库配置 注意 synchronize: true 配置项为 true 代表每次保存程序后 NEST 会根据实体类关系,动态创建修改数据库表结构,因此在开发环境此参数需要设置为 false,防止更改线上的数据库结构,这样在开发环境设置 synchronize: true 后,保存时会自动创建数据库中表结构
  8. 多对多关系中,建立的中间表是没有主键列的,只有两个 id 列
  9. Repository 中的 save 方法(没有主键则插入,有主键则修改)场景一:可作为 插入 方法使用,没有自动插入场景二:可作为 修改 方法使用,但是修改是可以修改实体的部分字段的,所以必须 Repository.find 查询出完整实体,然后使用 Repository.merge 合并后再 save 场景三:不存在主键插入,存在主键更新,使用方式与 场景二 相同场景四:由于 save 方法可以传入实体列表,所以可以用于 批量插入&修改
  10. Repository 中的 save 方法修改是针对于实体的,update 方法则是针对实体中的部分字段的

总结

  1. 简单 sql 操作优先使用 Repository API 实现,推荐:当前 实体类 下当前表的增删改、查单条、查所有 这些逻辑用 Repository API
  2. 复杂 sql 考虑使用 QueryBuilder 实现
  3. 及其复杂的操作或者性能有关的关键操作,考虑使用原声 sql

外键选择

生产环境可不添加外键(避免级联删除 / 更新的风险),改为应用层控制关联关系; 若需外键,可添加:ALTER TABLE sys_user_role ADD FOREIGN KEY (user_id) REFERENCES sys_user(id);。